package com.ningxun.pagent.bus.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSON;
import com.ningxun.pagent.bus.mapper.BusPolicyApproveMapper;
import com.ningxun.pagent.common.core.domain.entity.SysRole;
import com.ningxun.pagent.common.core.domain.model.LoginUser;
import com.ningxun.pagent.common.utils.DateUtils;
import com.ningxun.pagent.common.utils.SecurityUtils;
import com.ningxun.pagent.flow.mapper.WarmFlowMapper;
import org.dromara.warm.flow.core.FlowEngine;
import org.dromara.warm.flow.core.dto.FlowParams;
import org.dromara.warm.flow.core.entity.Instance;
import org.dromara.warm.flow.core.entity.Task;
import org.dromara.warm.flow.core.enums.SkipType;
import org.dromara.warm.flow.core.exception.FlowException;
import org.dromara.warm.flow.core.service.InsService;
import org.dromara.warm.flow.core.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ningxun.pagent.bus.mapper.BusPolicyContentMapper;
import com.ningxun.pagent.bus.domain.BusPolicyContent;
import com.ningxun.pagent.bus.service.IBusPolicyContentService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import static com.ningxun.pagent.common.utils.PageUtils.startPage;
import static com.ningxun.pagent.flow.constant.FlowConstant.*;

/**
 * 政策内容Service业务层处理
 *
 * @author pagent
 * @date 2025-07-10
 */
@Service
public class BusPolicyContentServiceImpl implements IBusPolicyContentService
{
    @Autowired
    private BusPolicyContentMapper busPolicyContentMapper;

    @Resource
    private BusPolicyApproveMapper busPolicyApproveMapper;

    @Resource
    private InsService insService;

    @Resource
    private TaskService taskService;

    @Resource
    private WarmFlowMapper warmFlowMapper;

    /**
     * 查询政策内容
     *
     * @param policyId 政策内容主键
     * @return 政策内容
     */
    @Override
    public BusPolicyContent selectBusPolicyContentByPolicyId(Long policyId)
    {
        return busPolicyContentMapper.selectBusPolicyContentByPolicyId(policyId);
    }

    /**
     * 查询政策内容列表
     *
     * @param busPolicyContent 政策内容
     * @return 政策内容
     */
    @Override
    public List<BusPolicyContent> selectBusPolicyContentList(BusPolicyContent busPolicyContent)
    {
        return busPolicyContentMapper.selectBusPolicyContentList(busPolicyContent);
    }

    /**
     * 新增政策内容
     *
     * @param busPolicyContent 政策内容
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int insertBusPolicyContent(BusPolicyContent busPolicyContent)
    {
        // 获取当前时间
        Date nowDate = DateUtils.getNowDate();
        /**
         *   自动设置审核状态为1（未审核） 已废弃 现在用工作流状态
         *   设置过期状态 前端会限制 所以是正常0
         */
        //busPolicyContent.setApproveStatus(1L);
        busPolicyContent.setInvalidState(0L);
        // 自动设置创建人信息
        busPolicyContent.setCreatorId(SecurityUtils.getUserId());
        busPolicyContent.setCreatorName(SecurityUtils.getUsername());
        // 设置流转参数
        LoginUser user = SecurityUtils.getLoginUser();
        // 从字典表中获取流程编码
        busPolicyContent.setType(FLOW_NAME);
        String flowCode = warmFlowMapper.getFlowCodeByFlowName(busPolicyContent.getType());
        
        // 先插入政策内容记录以获取policyId
        busPolicyContent.setCreateTime(nowDate);
        int contentResult = busPolicyContentMapper.insertBusPolicyContent(busPolicyContent);
        if (contentResult <= 0) {
            throw new RuntimeException("插入政策内容表失败");
        }
        
        // 传递流程编码，绑定流程定义 【必传】
        FlowParams flowParams = FlowParams.build().flowCode(flowCode);
        // 设置办理人唯一标识，保存为流程实例的创建人 【必传】
        flowParams.handler(user.getUser().getUserId().toString());
        Long id = busPolicyContent.getPolicyId();
        Instance instance = insService.start(String.valueOf(id), flowParams);
        
        // 重要：设置实例ID到政策内容对象
        busPolicyContent.setInstanceId(instance.getId());
        
        // 获取第一个任务节点，用于设置初始状态
        List<Task> tasks = FlowEngine.taskService().getByInsId(instance.getId());
        if (!tasks.isEmpty()) {
            Task firstTask = tasks.get(0);
            busPolicyContent.setNodeCode(firstTask.getNodeCode());
            busPolicyContent.setNodeName(firstTask.getNodeName());
            busPolicyContent.setNodeType(Long.valueOf(firstTask.getNodeType()));
            busPolicyContent.setFlowStatus(instance.getFlowStatus());
        } else {
            // 如果没有任务，默认设置为流程实例状态
            busPolicyContent.setNodeCode(instance.getNodeCode());
            busPolicyContent.setNodeName(instance.getNodeName());
            busPolicyContent.setNodeType(Long.valueOf(instance.getNodeType()));
            busPolicyContent.setFlowStatus(instance.getFlowStatus());
        }
        
        // 再次更新政策内容表，包含实例ID和流程状态
        busPolicyContentMapper.updateBusPolicyContent(busPolicyContent);

        return contentResult;
    }

    /**
     * 修改政策内容
     *
     * @param busPolicyContent 政策内容
     * @return 结果
     */
    @Override
    public int updateBusPolicyContent(BusPolicyContent busPolicyContent)
    {
        //查询原始数据
        BusPolicyContent old = busPolicyContentMapper.selectBusPolicyContentFieldsById(busPolicyContent.getPolicyId());
        if (old == null) {
            busPolicyContent.setModifyTime(DateUtils.getNowDate());
            return busPolicyContentMapper.updateBusPolicyContent(busPolicyContent);
        }

        //判断内容是否有变化
        boolean changed = false;
        if (!Objects.equals(old.getTitle(), busPolicyContent.getTitle())) changed = true;
        if (!Objects.equals(old.getContent(), busPolicyContent.getContent())) changed = true;
        if (!Objects.equals(old.getExpirationTime(), busPolicyContent.getExpirationTime())) changed = true;
        if (!Objects.equals(old.getPolicyType(), busPolicyContent.getPolicyType())) changed = true;
        if (!Objects.equals(old.getCreatorName(), busPolicyContent.getCreatorName())) changed = true;
        if (!Objects.equals(old.getInvalidState(), busPolicyContent.getInvalidState())) changed = true;

        if (changed) {
            busPolicyContent.setModifyTime(DateUtils.getNowDate());
            busPolicyContent.setApproveStatus(1L);//改为待审核状态
            //同步更新审核表的审核状态
           busPolicyApproveMapper.updateApproveStateByPolicyId(busPolicyContent.getPolicyId());
        } else {
            busPolicyContent.setModifyTime(old.getModifyTime());
        }

        return busPolicyContentMapper.updateBusPolicyContent(busPolicyContent);
    }

    /**
     * 修改政策内容（包含工作流逻辑）
     * 如果当前为"待提交"状态，修改后自动流转到"审批"节点
     *
     * @param busPolicyContent 政策内容
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int updateBusPolicyContentWithWorkflow(BusPolicyContent busPolicyContent) {
        // 1. 先执行普通的更新操作
        int result = updateBusPolicyContent(busPolicyContent);
        
        if (result > 0) {
            // 2. 查询更新后的最新数据
            BusPolicyContent updated = busPolicyContentMapper.selectBusPolicyContentByPolicyId(busPolicyContent.getPolicyId());
            
            // 3. 如果当前为"待提交"状态，自动提交到"审批"节点
            // 被退回后flowStatus=9，且必须是在beforeSubmit节点才能自动流转
            boolean isRejectedStatus = "9".equals(updated.getFlowStatus());
            boolean isBeforeSubmitNode = "beforeSubmit".equals(updated.getNodeCode());
            
            // 必须同时满足两个条件：被退回状态 AND 在待提交节点
            if (updated != null && isRejectedStatus && isBeforeSubmitNode) {
                try {
                    // 查找当前待提交的任务
                    List<Task> tasks = FlowEngine.taskService().getByInsId(updated.getInstanceId());
                    
                    if (!tasks.isEmpty()) {
                        // 找到当前政策对应的待提交节点任务
                        // 首先按节点编码精确匹配
                        Task submitTask = tasks.stream()
                            .filter(task -> "beforeSubmit".equals(task.getNodeCode()))
                            .findFirst()
                            .orElse(null);
                        
                        // 如果没找到beforeSubmit节点，尝试按节点名称匹配
                        if (submitTask == null) {
                            submitTask = tasks.stream()
                                .filter(task -> "待提交".equals(task.getNodeName()))
                                .findFirst()
                                .orElse(null);
                        }
                        
                        
                        if (submitTask != null) {
                            // 设置流转参数
                            LoginUser user = SecurityUtils.getLoginUser();
                            FlowParams flowParams = FlowParams.build().skipType(SkipType.PASS.getKey());
                            flowParams.handler(user.getUser().getUserId().toString());
                            
                            // 设置审批节点的办理人权限 - 固定为角色ID 1和100的用户可以审批
                            List<String> permissionList = new ArrayList<>();
                            permissionList.add("role:1");   // 角色ID为1的用户
                            permissionList.add("role:100"); // 角色ID为100的用户
                            flowParams.permissionFlag(permissionList);
                            
                            // 设置流程变量
                            Map<String, Object> variable = new HashMap<>();
                            variable.put("businessType", "busPolicyContent");
                            variable.put("action", "RESUBMIT"); // 重新提交
                            flowParams.variable(variable);
                            flowParams.message("政策修改后重新提交审批");
                            
                            // 执行流程流转
                            Instance instance = taskService.skip(submitTask.getId(), flowParams);
                            
                            // 更新政策内容表的流程状态
                            updated.setNodeCode(instance.getNodeCode());
                            updated.setNodeName(instance.getNodeName());
                            updated.setNodeType(Long.valueOf(instance.getNodeType()));
                            updated.setFlowStatus(instance.getFlowStatus());
                            updated.setUpdateTime(DateUtils.getNowDate());
                            
                            busPolicyContentMapper.updateBusPolicyContent(updated);
                        }
                        }
                } catch (Exception e) {
                    // 自动流转失败不影响主要的更新操作
                }
            }
        }
        
        return result;
    }

    /**
     * 批量删除政策内容
     *
     * @param policyIds 需要删除的政策内容主键
     * @return 结果
     */
    @Override
    public int deleteBusPolicyContentByPolicyIds(Long[] policyIds)
    {
        return busPolicyContentMapper.deleteBusPolicyContentByPolicyIds(policyIds);
    }

    /**
     * 删除政策内容信息
     *
     * @param policyId 政策内容主键
     * @return 结果
     */
    @Override
    public int deleteBusPolicyContentByPolicyId(Long policyId)
    {
        return busPolicyContentMapper.deleteBusPolicyContentByPolicyId(policyId);
    }

    @Override
    public void checkExpire() {
        //查询生效列表
        List<BusPolicyContent> list = busPolicyContentMapper.selectState();

        Date now = new Date();
        for(BusPolicyContent content : list){
            if(content.getExpirationTime() != null && content.getExpirationTime().before(now)){
                //过期：
                content.setInvalidState(1L);//设为失效
                busPolicyContentMapper.updateBusPolicyContent(content);
            }
        }
    }

    /**
     * 提交政策审批
     * @param policyId
     * @param approveStatus
     * @return
     */
    @Override
    public int submit(Long policyId, Long approveStatus) {
        // 设置流转参数
        BusPolicyContent busPolicyContent = busPolicyContentMapper.selectBusPolicyContentByPolicyId(policyId);
        LoginUser user = SecurityUtils.getLoginUser();
        // 是通过流程还是退回流程  【必传】
        FlowParams flowParams = FlowParams.build().skipType(SkipType.PASS.getKey());
        // 作为办理人保存到历史记录表 【必传】
        flowParams.handler(user.getUser().getUserId().toString());
        // 设置办理人拥有的权限，办理中需要校验是否有权限办理 【必传】
        List<SysRole> roles = user.getUser().getRoles();
        List<String> permissionList = new ArrayList<>();
        if (Objects.nonNull(roles)) {
            permissionList = roles.stream().map(role -> "role:" + role.getRoleId()).collect(Collectors.toList());
        }
        permissionList.add("dept:" + SecurityUtils.getLoginUser().getUser().getDeptId());
        permissionList.add(user.getUser().getUserId().toString());
        flowParams.permissionFlag(permissionList);

        // 更新政策内容表
        Instance instance = taskService.skipByInsId(busPolicyContent.getInstanceId(), flowParams);
        busPolicyContent.setNodeCode(instance.getNodeCode());
        busPolicyContent.setNodeName(instance.getNodeName());
        busPolicyContent.setNodeType(Long.valueOf(instance.getNodeType()));
        busPolicyContent.setFlowStatus(instance.getFlowStatus());
        busPolicyContent.setUpdateTime(DateUtils.getNowDate());
        return busPolicyContentMapper.updateBusPolicyContent(busPolicyContent);
    }

    /**
     * 处理政策审核
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int handle(BusPolicyContent busPolicyContent, String skipType, Long taskId,
                                      String message, String nodeCode, String flowStatus)
    {
        // 设置流转参数
        LoginUser user = SecurityUtils.getLoginUser();
        // 是通过流程还是退回流程 【必传】
        FlowParams flowParams = FlowParams.build().skipType(skipType);
        // 作为办理人保存到历史记录表 【必传】
        flowParams.handler(user.getUser().getUserId().toString());
        // 作为审批意见保存到历史记录表  【按需传】
        flowParams.message(message);

        // 设置办理人拥有的权限，办理中需要校验是否有权限办理 【必传】
        List<SysRole> roles = user.getUser().getRoles();
        List<String> permissionList = new ArrayList<>();
        if (Objects.nonNull(roles)) {
            permissionList = roles.stream().map(role -> "role:" + role.getRoleId()).collect(Collectors.toList());
        }
        permissionList.add("dept:" + SecurityUtils.getLoginUser().getUser().getDeptId());
        permissionList.add(user.getUser().getUserId().toString());
        flowParams.permissionFlag(permissionList);

        // Todo
        //taskId = 1404899021717377024L;
        Task task = FlowEngine.taskService().getById(taskId);
        if (task == null) {
            throw new FlowException("未找到待办任务，请刷新页面重试");
        }

//        // 验证任务状态
//        if (!"1".equals(task.getFlowStatus())) { // 假设"1"表示待办状态
//            throw new FlowException("任务状态不正确，可能已被处理");
//        }

        // 流程变量
        Map<String, Object> variable = new HashMap<>();
        // 流程变量传递业务数据，按实际业务需求传递  【按需传】
        variable.put("businessType", "busPolicyContent");
        
        // 根据skipType设置不同的处理逻辑
        if (REJECT.equals(skipType)) {
            // 退回操作
            variable.put("decision", "REJECT");
            variable.put("action", "REJECT");
            // 设置审批状态为驳回
            busPolicyContent.setApproveStatus(2L); // 2表示驳回
        } else if (PASS.equals(skipType)) {
            // 通过操作
            variable.put("decision", "PASS");
            variable.put("action", "APPROVE");
            // 设置审批状态为通过
            busPolicyContent.setApproveStatus(0L); // 0表示通过
        }
        
        // 办理人表达式替换  【按需传】
        variable.put("flag", busPolicyContent.getApproveStatus());
        flowParams.variable(variable);

        // 审核信息存入flowParams,方便查看历史审批数据  【按需传】
        flowParams.hisTaskExt(JSON.toJSONString(busPolicyContent));
        Instance instance = taskService.skip(taskId, flowParams);

        busPolicyContent.setNodeCode(instance.getNodeCode());
        busPolicyContent.setNodeName(instance.getNodeName());
        busPolicyContent.setNodeType(Long.valueOf(instance.getNodeType()));
        busPolicyContent.setFlowStatus(instance.getFlowStatus());
        
        // 保存审批意见到comment字段
        busPolicyContent.setComment(message);

        // 获取当前时间
        Date nowDate = DateUtils.getNowDate();

        // 封装政策内容表对象
        busPolicyContent.setModifyTime(nowDate);
        int contentResult = busPolicyContentMapper.updateBusPolicyContent(busPolicyContent);
        if (contentResult <= 0) {
            throw new RuntimeException("修改政策内容表失败");
        }

        return contentResult;
    }

    /**
     * 驳回政策审核
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int rejectLast(BusPolicyContent busPolicyContent, Long taskId, String message, String flowStatus) {
        // 设置流转参数
        LoginUser user = SecurityUtils.getLoginUser();
        FlowParams flowParams = FlowParams.build();
        // 作为办理人保存到历史记录表 【必传】
        flowParams.handler(user.getUser().getUserId().toString());
        // 作为审批意见保存到历史记录表  【按需传】
        flowParams.message(message);

        // 设置办理人拥有的权限，办理中需要校验是否有权限办理 【必传】
        List<SysRole> roles = user.getUser().getRoles();
        List<String> permissionList = new ArrayList<>();
        if (Objects.nonNull(roles)) {
            permissionList = roles.stream().map(role -> "role:" + role.getRoleId()).collect(Collectors.toList());
        }
        permissionList.add("dept:" + SecurityUtils.getLoginUser().getUser().getDeptId());
        permissionList.add(user.getUser().getUserId().toString());
        flowParams.permissionFlag(permissionList);

        // 审核信息存入flowParams,方便查看历史审批数据  【按需传】
        flowParams.hisTaskExt(JSON.toJSONString(busPolicyContent));
        Instance instance = taskService.rejectLast(taskId, flowParams);

        // 更新请假表
        busPolicyContent.setNodeCode(instance.getNodeCode());
        busPolicyContent.setNodeName(instance.getNodeName());
        busPolicyContent.setNodeType(Long.valueOf(instance.getNodeType()));
        busPolicyContent.setFlowStatus(instance.getFlowStatus());
        return busPolicyContentMapper.updateBusPolicyContent(busPolicyContent);
    }

    //前端查详情
    @Override
    public BusPolicyContent selectFrontBusPolicyContentByPolicyId(Long policyId) {
        return busPolicyContentMapper.selectBusPolicyContentByPolicyId(policyId);
    }

    //获取最新政策
    @Override
    public List<BusPolicyContent> selectLatestPolicies(int limit) {
        return busPolicyContentMapper.selectLatestPolicies(limit);
    }

    @Override
    public List<BusPolicyContent> selectBusPolicyContentByPolicyIdList(List<Long> policyIds) {
        if (policyIds == null || policyIds.isEmpty()) {
            return new ArrayList<>();
        }
        return busPolicyContentMapper.selectBusPolicyContentByPolicyIdList(policyIds);
    }
}
